/*
 *  Model.c
 *  graphics1
 *
 *  Created by Javier Quevedo on 12/7/08.
 *  Copyright 2008 __MyCompanyName__. All rights reserved.
 *
 */

#include "Model.h"

#if defined(WIN32)
#include <GL/glut.h>
#else
#include <GLUT/glut.h>
#endif

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void LoadModel(Model *modelElement , char  **modelFiles, int numFiles)
{
	FILE *file; 
 	modelElement->modelParts = malloc(sizeof(ModelPart)*numFiles);
	printf(modelFiles[0]);
	int nFile = 0;
	int i=0;
	
	modelElement->partCount = numFiles;
	
	for (nFile = 0; nFile < numFiles; nFile++)
	{
		printf("Modelpart: %s\n",modelFiles[nFile]);
		file = fopen(modelFiles[nFile], "r");

		
		ModelPart *part = malloc(sizeof(ModelPart));
		//part->layers  = malloc(sizeof(layerStruct));
		modelElement->modelParts[nFile] = part;
		part->texture=NULL;
		//layerStruct **layers = malloc(sizeof(layerStruct));
		part->layers =  malloc(sizeof(LayerStruct));

		// Each part of the file
		int layerCounter = 0;
		
		char *lineSkip;
		while (layerCounter > -1)
			{
				layerCounter++;
				part->layerCount = layerCounter;
				LayerStruct *layer = malloc(sizeof(LayerStruct));
				part->layers = realloc(part->layers, sizeof(LayerStruct)*layerCounter);
				part->layers[layerCounter-1] = layer;

				fscanf (file , "%s %d\n", &layer->modelType , &layer->vertexCount);
				fscanf (file , "%f %f %f %f\n", &layer -> r , &layer -> g, &layer -> b, &layer -> alpha);
	
				layer->vertexX = malloc(sizeof(float)* (layer-> vertexCount));
				layer->vertexY = malloc(sizeof(float)* (layer-> vertexCount));
				layer->vertexZ = malloc(sizeof(float)* (layer-> vertexCount));
	
				layer->normalX = malloc(sizeof(float)* (layer-> vertexCount));
				layer->normalY = malloc(sizeof(float)* (layer-> vertexCount));
				layer->normalZ = malloc(sizeof(float)* (layer-> vertexCount));

				for (i=0; i < layer->vertexCount; i++)
				{
					fscanf (file , "%f %f %f %f %f %f\n", &layer -> vertexX[i], &layer -> vertexY[i], &layer -> vertexZ[i],
										&layer -> normalX[i], &layer -> normalY[i], &layer -> normalZ[i]);	
					//printf("Drawing vertex: %f, %f, %f \n", layer->vertexX[i], layer->vertexY[i], layer->vertexZ[i]);
				}
				//char *likeSkip = fgetc(file);

				if (feof(file))
					layerCounter = -1;
			}
		fclose(file);
	}

}

void renderPart (ModelPart *part)
{
	if (part == NULL)
		return;
	int i = 0;
	int nLayer = 0;
	for (nLayer = 0; nLayer < part->layerCount; nLayer++)
	{
		LayerStruct *model = part->layers[nLayer];
		if (part->texture != NULL){
			glEnable( GL_TEXTURE_2D );
			glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
			glBindTexture( GL_TEXTURE_2D, part->texture->textureName);	
		}
		float mcolor[] = { 0.5f, 0.5f, 0.5f, 1.0f };
		glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mcolor);
		glColor3f(model->r, model->g, model->b);
		
		//printf("Model is:%s.",model->modelType);
		if (strcmp(model->modelType, "QUADS") == 0)
			glBegin (GL_QUADS);	
		else if (strcmp(model->modelType, "TRIANGLES") == 0)
			glBegin (GL_TRIANGLES);			
		else if (strcmp(model->modelType, "LINE_STRIP") == 0)
			glBegin (GL_LINE_STRIP);	
		
		else if (strcmp(model->modelType, "POINTS") == 0)
			glBegin (GL_POINTS);	
		
		else if (strcmp(model->modelType, "LINES") == 0)
			glBegin (GL_LINES);
		
		else if (strcmp(model->modelType, "LINE_LOOP") == 0)
			glBegin (GL_LINE_LOOP);		
		
		else if (strcmp(model->modelType, "TRIANGLE_STRIP") == 0)
			glBegin (GL_TRIANGLE_STRIP);
		
		else if (strcmp(model->modelType, "TRIANGLE_FAN")== 0)
			glBegin (GL_TRIANGLE_FAN);
		
		else if (strcmp(model->modelType, "QUAD_STRIP")== 0)
			glBegin (GL_QUAD_STRIP);	
		
		else if (strcmp(model->modelType, "POLYGON")== 0 )
			glBegin (GL_POLYGON);
		
		
		for (i = 0; i< model->vertexCount; i++)
		{
			//printf("Drawing normal: %f, %f, %f \n", model->normalX[i], model->normalY[i], model->normalZ[i]);

			glNormal3f(model->normalX[i],model->normalY[i], model->normalZ[i]);
		if (part->texture != NULL)
				glTexCoord2f(model->vertexX[i], model->vertexY[i]);
				
			glVertex3f(model->vertexX[i], model->vertexY[i], model->vertexZ[i]);
			
		}	
		glEnd();
		
		glDisable(GL_TEXTURE_2D);
	}
}



void drawModel (Model *modelElement)
{
	int nPart = 0;
	int i=0;
	ModelPart *part;
	for (nPart = 0; nPart < modelElement->partCount; nPart++)
	{
		 renderPart(modelElement->modelParts[nPart]);
	}
}

